﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using TimScripts.BF4Rcon.Frostbite.Resources;

namespace TimScripts.BF4Rcon.Frostbite
{
    public class RconConnection : StreamRconConnection, IDisposable
    {
        private TcpClient Client;
        private bool Disposed = false;
        private object ClientLock = new object();

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Hostname")]
        public string Hostname { get; set; }

        private int _Port;
        public int Port
        {
            get
            {
                return _Port;
            }

            set
            {
                if (value < IPEndPoint.MinPort || value > IPEndPoint.MaxPort)
                    throw new ArgumentOutOfRangeException("value");

                _Port = value;
            }
        }

        public override void Connect()
        {
            lock (ClientLock)
            {
                if (Client != null)
                    throw new InvalidOperationException(ErrorStrings.InvalidOperation_AlreadyConnected);

                Client = new TcpClient(Hostname, Port);

                SetStream(Client.GetStream());
            }
        }

        public override void Disconnect()
        {
            lock (ClientLock)
            {
                if (Client == null) return;

                Client.Close();
                Client = null;
            }
        }

        public override bool IsConnected
        {
            get
            {
                lock (ClientLock)
                {
                    return Client != null && Client.Connected;
                }
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!Disposed)
            {
                if (disposing)
                {
                    Disconnect();
                }
            }
        }
    }
}
